// Copyright (c) 2024-present AI-Labs

// @ ts-nocheck
// https://www.diagrams.com/doc/faq/embed-mode
export class DiagramEditor {
    frame: HTMLIFrameElement | undefined
    container: string
    domain = 'https://embed.diagrams.net'
    // https://www.drawio.com/doc/faq/supported-url-parameters
    params = {
        ui: 'atlas',
        proto: 'json',
        libraries: 1,
        configure: 1,
        noSaveBtn: 1,
    }
    xml: string | null = null
    format = 'xmlsvg'
    data: any

    constructor({
        domain,
        params,
        container,
    }: {
        domain?: string
        params?: Record<string, any>
        container: string
    }) {
        this.domain = domain ?? this.domain
        this.params = { ...params, ...this.params }
        this.container = container
    }

    handleuseMessageEvent = (evt: MessageEvent) => {
        if (
            this.frame !== undefined &&
            evt.source === this.frame.contentWindow &&
            evt.data.length > 0
        ) {
            try {
                const msg = JSON.parse(evt.data)
                if (msg) {
                    this.handleuseMessage(msg)
                }
            } catch (e) {
                console.error(e)
            }
        }
    }

    // 编辑元素
    edit(src: string) {
        let fmt = this.format
        if (src.substring(0, 15) === 'data:image/png;') {
            fmt = 'xmlpng'
        } else if (src.substring(0, 19) === 'data:image/svg+xml;') {
            fmt = 'xmlsvg'
        }
        this.startEditing(src, fmt)
        return this
    }

    // 创建 iframe
    createFrame() {
        const params = Object.keys(this.params)
            .map((key) => `${key}=${this.params[key as keyof typeof this.params]}`)
            .join('&')
        const frame = document.createElement('iframe')
        frame.setAttribute('class', 'uai-diagrams-iframe')
        frame.setAttribute('src', `${this.domain}?${params}&lang=zh`)
        return frame
    }

    // diagrams页面和当前页面通信
    postMessage(msg: Record<string, any>) {
        if (this.frame) {
            this.frame.contentWindow?.postMessage(JSON.stringify(msg), '*')
        }
    }
    handleuseMessage(msg: {
        event: string
        data: any
        xml: string
        exit: boolean
    }) {
        if (msg.event === 'configure') {
            this.configureEditor()
        } else if (msg.event === 'init') {
            this.initializeEditor()
        } else if (msg.event === 'save') {
            this.export(msg.data)
            this.xml = msg.xml
            if (msg.exit) {
                msg.event = 'exit'
            } else {
                this.postMessage({
                    action: 'status',
                    messageKey: 'allChangesSaved',
                    modified: false,
                })
            }
        }
        if (msg.event === 'exit') {
            if (this.format !== 'xml') {
                if (this.xml) {
                    this.postMessage({
                        action: 'export',
                        format: this.format,
                        xml: this.xml,
                        spinKey: 'export',
                    })
                }
            }
            this.stopEditing()
        }
    }

    // 开始编辑
    startEditing(data: any, format: string) {
        if (!this.frame) {
            window.addEventListener('message', this.handleuseMessageEvent)
            this.format = format ?? this.format
            this.data = data
            this.frame = this.createFrame()
            const container = document.querySelector(this.container)
            container?.appendChild(this.frame)
        }
    }

    // 停止编辑
    stopEditing() {
        window.removeEventListener('message', this.handleuseMessageEvent)
        this.frame = undefined
    }

    // 安装编辑器
    initializeEditor() {
        this.postMessage({
            action: 'load',
            autosave: 0,
            saveAndExit: '1',
            modified: 'unsavedChanges',
            xml: this.data,
        })
    }

    // 设置编辑器
    configureEditor() {
        this.postMessage({ action: 'configure', config: this.params.configure })
    }
    // 导出数据
    export(data: any) {
        return data
    }
}
